/**
 * 代码评审详情概览页动态组件
 */
import React from 'react';
import PropTypes from 'prop-types';
import hljs from 'utils/hl.js';
import { Tag, Balloon } from '@teamix/ui';
import { YunxiaoIcon } from '@alife/devops-ui';
import utils from 'utils/index';
import MarkdownIt from 'markdown-it';
import { Link, navigateOpen } from 'utils/router';
import TextAvatar from '@txdfe/at-text-avatar';
import BuildsResultTag from 'components/buildsResultTag';
import { filterXSS } from 'xss';
import CommentLog from './comment';
import intl from '../../../../../../../../../locale';

const md = new MarkdownIt({
  highlight(str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return hljs.highlight(lang, str).value;
      } catch (__) {
        return '';
      }
    }

    return ''; // 使用额外的默认转义
  },
});

const iconMapper = {
  APPROVE: 'add-members-line',
  MERGE: 'merge-line',
  SEE: 'member-line',
  REMOVE: 'member-line',
  PUSH: 'commit-line',
  CLOSE: 'false-line',
  REOPEN: 'timed-refresh-line',
  ACCEPT: 'success-fill',
  OTHER: 'setting-line',
  BOT: 'robot-line',
  AUTHOR: 'message-group-line',
};
export default class CodeReviewLogMedia extends React.Component {
  static propTypes = {
    log: PropTypes.object,
    projectInfo: PropTypes.object,
  };

  constructor(props) {
    super(props);

    this.state = {
      isMsgDescVisible: false, // 提交信息的描述部分（即第一个换行符后的部分）默认隐藏，点...展开
    };
  }

  onChange = (e, id) => {
    e.preventDefault();

    const { pathResource } = window.FORCE;
    navigateOpen(`/${pathResource.fullPath}/commit/${id}?branch=${id}`, '_blank');
  };

  /**
   * 操作类型到展示图标的转换
   *
   * @param avatarType
   * @returns {*}
   */
  logIconJsx(avatarType) {
    let iconType = iconMapper.OTHER;
    if (iconMapper[avatarType]) {
      iconType = iconMapper[avatarType];
    }

    let curIcon = null;

    if (avatarType === 'MERGE' || avatarType === 'BOT' || avatarType === 'PUSH') {
      curIcon = <YunxiaoIcon type={iconType} />;
    } else {
      curIcon = <YunxiaoIcon type={iconType} />;
    }

    return (
      <div className="log-item-icon">
        {curIcon}
        <div className="log-line" />
      </div>
    );
  }

  /**
   * 展示一个操作历史项目，可能是系统操作，也可能是评论
   *
   * @param log
   * @returns {*}
   */
  logPUSHContentJsx(log) {
    const { isMsgDescVisible } = this.state;
    const { projectInfo } = this.props;
    const { fullPath } = window.FORCE.pathResource;
    const pushMessage = log.note.split('\n\n');
    const pushCommitTitle = pushMessage[0].split(':');
    const pushCommit = pushMessage[1] ? pushMessage[1].split('\n') : '';
    const pushCommitArr = pushCommit ? pushCommit.map((item) => item.split('- ')) : '';
    const pushCommitdesc = pushCommitArr ? pushCommitArr.map((item) => item.slice(1)) : '';
    const pushCommitCompare = pushCommitTitle[1] && pushCommitTitle[1].split(',');
    const pushCommitCompareMore =
      pushCommitCompare && pushCommitCompare.length === 1 && pushCommitCompare[0].split('...');
    return (
      <>
        <div className="log-item-title">
          <div className="log-item-title-info commit-logs">
            <div className="log-item-title-author">
              {log.author_name ===
              intl.get({
                id: 'code-assets.components.logs.logItem.KidneyBeans',
                defaultMessage: '云豆',
              }) ? (
                <TextAvatar
                  image="https://img.alicdn.com/tfs/TB1WYSpIQL0gK0jSZFtXXXQCXXa-400-401.png"
                  text={log.author_name}
                  // needAddedText
                  size="xs"
                />
              ) : (
                <TextAvatar
                  image={log.author_avatar_url}
                  text={log.author_name}
                  // needAddedText
                  size="xs"
                />
              )}
            </div>
            <div className="note-user-name">{log.author_name}</div>
            {log.author_name ===
              intl.get({
                id: 'code-assets.components.logs.logItem.KidneyBeans',
                defaultMessage: '云豆',
              }) && (
              <div className="log-item-title-author-tag">
                <Tag>bot</Tag>
              </div>
            )}
            {log.author_name ===
            intl.get({
              id: 'code-assets.components.logs.logItem.KidneyBeans',
              defaultMessage: '云豆',
            }) ? null : (
              <span>&nbsp;</span>
            )}
            <div className="log-item-title-content">{pushCommitTitle[0]}</div>
            &nbsp;
            <div>
              {pushCommitCompare &&
                pushCommitCompare.length === 1 &&
                pushCommitCompareMore.length < 2 && (
                  <a
                    className="text-black desc-title-lh"
                    onClick={(e) => this.onChange(e, pushCommitCompare[0].trim())}
                  >
                    {pushCommitCompare[0].slice(0, 8)}
                  </a>
                )}

              {pushCommitCompare && pushCommitCompare.length === 2 && (
                <Link
                  to={`/${fullPath}/compare?from=${encodeURIComponent(
                    pushCommitCompare[0],
                  )}&to=${encodeURIComponent(pushCommitCompare[1])}&tab=activity`}
                  className="text-black"
                >
                  {pushCommitCompare[0].slice(0, 8)},{pushCommitCompare[1].slice(0, 8)}
                </Link>
              )}

              {pushCommitCompareMore && pushCommitCompareMore.length >= 2 && (
                <Link
                  to={`/${fullPath}/compare?from=${encodeURIComponent(
                    pushCommitCompareMore[0],
                  )}&to=${encodeURIComponent(pushCommitCompareMore[1])}&tab=activity`}
                  className="text-black"
                >
                  {pushCommitCompareMore[0].slice(0, 8)}...{pushCommitCompareMore[1].slice(0, 8)}
                </Link>
              )}
            </div>
            {pushCommitArr ? (
              <span
                className="show-more-span"
                onClick={() => {
                  this.setState({
                    isMsgDescVisible: !isMsgDescVisible,
                  });
                }}
              >
                <YunxiaoIcon
                  type={isMsgDescVisible ? 'arrow-up-2-line' : 'arrow-down-2-line'}
                  className="show-more-icon"
                />
              </span>
            ) : null}
          </div>
          <div className="log-item-title-time">{utils.getBeautyTime(log.created_at)}</div>
        </div>
        {/* commit列表 */}
        <div className="log-item-detail">
          {pushCommitdesc && isMsgDescVisible ? (
            <div className="log-item-push-list">
              {pushCommitdesc.map((item) => (
                <div className="log-item-push-list-item">
                  <a
                    onClick={(e) => {
                      this.onChange(e, item[0].trim());
                    }}
                    className="sha"
                  >
                    {item[0].substring(0, 8)}
                  </a>
                  <Balloon.Tooltip trigger={<span className="mr-detail-logs-balloon">{item[1]}</span>} closable={false}>
                    <span>{item[1]}</span>
                  </Balloon.Tooltip>
                  <BuildsResultTag
                    container={{
                      target: 'commit', // 可选值为 commit 和 merge_request
                      id: item[0], // commit 或 merge_request 的 id
                    }}
                    projectInfo={projectInfo}
                  />
                </div>
              ))}
            </div>
          ) : null}
        </div>
      </>
    );
  }

  logItemContentJsx(item) {
    const isYundouComment =
      item.avatarType === 'BOT' &&
      item.noteData.some((note) => {
        return note.issue;
      });
    // 评论或者云豆回复
    if (item.authorDTO || isYundouComment) {
      return <CommentLog {...this.props} />;
    }
    // 系统操作，有且仅有一条note
    const log = item.noteData[0].noteList[0];
    if (item.avatarType === 'PUSH') {
      return this.logPUSHContentJsx(log);
    }
    return (
      <div className="log-item-title has-pb">
        <div className="log-item-title-info normal">
          <div className="log-item-title-author">
            {log.author_name ===
            intl.get({
              id: 'code-assets.components.logs.logItem.KidneyBeans',
              defaultMessage: '云豆',
            }) ? (
              <div className="log-item-title-author-yundou">
                <TextAvatar
                  image="https://img.alicdn.com/tfs/TB1WYSpIQL0gK0jSZFtXXXQCXXa-400-401.png"
                  text={log.author_name}
                  // needAddedText
                  size="xs"
                />
              </div>
            ) : (
              <TextAvatar
                image={log.author_avatar_url}
                text={log.author_name}
                // needAddedText
                size="xs"
              />
            )}
          </div>

          <div className="note-content-wrapper">
            <div className="note-user-name">
              <span>{log.author_name}</span>
              {log.author_name ===
                intl.get({
                  id: 'code-assets.components.logs.logItem.KidneyBeans',
                  defaultMessage: '云豆',
                }) && (
                <span className="log-item-title-author-tag">
                  <Tag>bot</Tag>
                </span>
              )}

              {log.author_name ===
              intl.get({
                id: 'code-assets.components.logs.logItem.KidneyBeans',
                defaultMessage: '云豆',
              }) ? null : (
                <span>&nbsp;</span>
              )}
            </div>

            <div
              className="mr-log-tooltip markdown-body"
              dangerouslySetInnerHTML={{
                __html: filterXSS(md.render(log.note || ''), {
                  onIgnoreTagAttr: (_, name, value) => {
                    return `${name}=${value}`;
                  },
                }),
              }}
            />
          </div>
        </div>
        <div className="log-item-title-time">{utils.getBeautyTime(log.created_at)}</div>
      </div>
    );
  }

  render() {
    const { log } = this.props;

    return (
      <React.Fragment>
        <div className="log-item">
          <div className="log-item-left">{this.logIconJsx(log.avatarType)}</div>
          <div className="log-item-right">{this.logItemContentJsx(log)}</div>
        </div>
      </React.Fragment>
    );
  }
}
